package com.gitee.huanminabc.jlambda_sql.warapper;

import com.gitee.huanminabc.jlambda_sql.base.SqlFun;

/**
 * 简要描述
 *
 * @Author: huanmin
 * @Date: 2025/4/6 12:16
 * @Version: 1.0
 * @Description: 文件作用详细描述....
 */
public class DefaultWhereWrapper<T, Children extends DefaultWrapper<T, Children>> extends DefaultWrapper<T, Children> implements WhereWrapper<Children, T> {

    public DefaultWhereWrapper(LambdaWrapper<T> typedThis) {
        super(typedThis);
    }

    @Override
    public Children IS_NULL(SqlFun<T, ?> column) {
        typedThis.getFunFieldName(column, sqlColumn -> {
            SQL().append(sqlColumn.getTableName()).append(".").append(sqlColumn.getColumnName()).append(" ");
            SQL().append(typedThis.IS_NULL());
        });
        typedThis.AND();
        return children;
    }

    @Override
    public Children IS_NULL(boolean condition, SqlFun<T, ?> column) {
        if (condition) {
            IS_NULL(column);
        }
        return children;
    }

    @Override
    public Children IS_NOT_NULL(SqlFun<T, ?> column) {
        typedThis.getFunFieldName(column, sqlColumn -> {
            SQL().append(sqlColumn.getTableName()).append(".").append(sqlColumn.getColumnName()).append(" ");
            SQL().append(typedThis.IS_NOT_NULL());
        });
        typedThis.AND();
        return children;
    }

    @Override
    public Children IS_NOT_NULL(boolean condition, SqlFun<T, ?> column) {
        if (condition) {
            IS_NOT_NULL(column);
        }
        return children;
    }

    @Override
    public Children EQ(SqlFun<T, ?> column, Object value) {
        typedThis.getFunFieldName(column, sqlColumn -> {
            SQL().append(sqlColumn.getTableName()).append(".").append(sqlColumn.getColumnName()).append(" ");
            SQL().append(typedThis.EQ()).append(typedThis.V(value));
        });
        typedThis.AND();
        return children;
    }

    @Override
    public Children EQ(boolean condition, SqlFun<T, ?> column, Object value) {
        if (condition) {
            EQ(column, value);
        }
        return children;
    }

    @Override
    public Children BETWEEN(SqlFun<T, ?> column, Object value1, Object value2) {
        typedThis.getFunFieldName(column, sqlColumn -> {
            SQL().append(sqlColumn.getTableName()).append(".").append(sqlColumn.getColumnName()).append(" ");
            SQL().append(typedThis.BETWEEN()).append(typedThis.V(value1)).append(typedThis.AND()).append(typedThis.V(value2));
        });
        typedThis.AND();
        return children;
    }

    @Override
    public Children BETWEEN(boolean condition, SqlFun<T, ?> column, Object value1, Object value2) {
        if (condition) {
            BETWEEN(column, value1, value2);
        }
        return children;
    }

    @Override
    public Children LIKE(SqlFun<T, ?> column, Object value) {
        typedThis.getFunFieldName(column, sqlColumn -> {
            SQL().append(sqlColumn.getTableName()).append(".").append(sqlColumn.getColumnName()).append(" ");
            SQL().append(typedThis.LIKE(value));
        });
        typedThis.AND();
        return children;
    }

    @Override
    public Children LIKE(boolean condition, SqlFun<T, ?> column, Object value) {
        if (condition) {
            LIKE(column, value);
        }
        return children;
    }

    @Override
    public Children LIKE_LEFT(SqlFun<T, ?> column, Object value) {
        typedThis.getFunFieldName(column, sqlColumn -> {
            SQL().append(sqlColumn.getTableName()).append(".").append(sqlColumn.getColumnName()).append(" ");
            SQL().append(typedThis.LIKE_LEFT(value));
        });
        typedThis.AND();
        return children;
    }

    @Override
    public Children LIKE_LEFT(boolean condition, SqlFun<T, ?> column, Object value) {
        if (condition) {
            LIKE_LEFT(column, value);
        }
        return children;
    }

    @Override
    public Children LIKE_RIGHT(SqlFun<T, ?> column, Object value) {
        typedThis.getFunFieldName(column, sqlColumn -> {
            SQL().append(sqlColumn.getTableName()).append(".").append(sqlColumn.getColumnName()).append(" ");
            SQL().append(typedThis.LIKE_RIGHT(value));
        });
        typedThis.AND();
        return children;
    }

    @Override
    public Children LIKE_RIGHT(boolean condition, SqlFun<T, ?> column, Object value) {
        if (condition) {
            LIKE_RIGHT(column, value);
        }
        return children;
    }

    @Override
    public Children IN(SqlFun<T, ?> column, Object... values) {
        if (values.length == 0) {
            throw new IllegalArgumentException("in values is empty");
        }
        typedThis.getFunFieldName(column, sqlColumn -> {
            SQL().append(sqlColumn.getTableName()).append(".").append(sqlColumn.getColumnName()).append(" ");
            SQL().append(typedThis.IN(values));
        });
        typedThis.AND();
        return children;
    }

    @Override
    public Children IN(boolean condition, SqlFun<T, ?> column, Object... values) {
        if (condition) {
            IN(column, values);
        }
        return children;
    }

    @Override
    public Children NOT_IN(SqlFun<T, ?> column, Object... values) {
        if (values.length == 0) {
            throw new IllegalArgumentException("not in values is empty");
        }
        typedThis.getFunFieldName(column, sqlColumn -> {
            SQL().append(sqlColumn.getTableName()).append(".").append(sqlColumn.getColumnName()).append(" ");
            SQL().append(typedThis.NOT_IN(values));
        });
        typedThis.AND();
        return children;
    }

    @Override
    public Children NOT_IN(boolean condition, SqlFun<T, ?> column, Object... values) {
        if (condition) {
            NOT_IN(column, values);
        }
        return children;
    }

    @Override
    public Children NE(SqlFun<T, ?> column, Object value) {
        typedThis.getFunFieldName(column, sqlColumn -> {
            SQL().append(sqlColumn.getTableName()).append(".").append(sqlColumn.getColumnName()).append(" ");
            SQL().append(typedThis.NE()).append(typedThis.V(value));
        });
        typedThis.AND();
        return children;
    }

    @Override
    public Children NE(boolean condition, SqlFun<T, ?> column, Object value) {
        if (condition) {
            NE(column, value);
        }
        return children;
    }

    @Override
    public Children GT(SqlFun<T, ?> column, Object value) {
        typedThis.getFunFieldName(column, sqlColumn -> {
            SQL().append(sqlColumn.getTableName()).append(".").append(sqlColumn.getColumnName()).append(" ");
            SQL().append(typedThis.GT()).append(typedThis.V(value));
        });
        typedThis.AND();
        return children;
    }

    @Override
    public Children GT(boolean condition, SqlFun<T, ?> column, Object value) {
        if (condition) {
            GT(column, value);
        }
        return children;
    }

    @Override
    public Children GE(SqlFun<T, ?> column, Object value) {
        typedThis.getFunFieldName(column, sqlColumn -> {
            SQL().append(sqlColumn.getTableName()).append(".").append(sqlColumn.getColumnName()).append(" ");
            SQL().append(typedThis.GE()).append(typedThis.V(value));
        });
        typedThis.AND();
        return children;
    }

    @Override
    public Children GE(boolean condition, SqlFun<T, ?> column, Object value) {
        if (condition) {
            GE(column, value);
        }
        return children;
    }

    @Override
    public Children LT(SqlFun<T, ?> column, Object value) {
        typedThis.getFunFieldName(column, sqlColumn -> {
            SQL().append(sqlColumn.getTableName()).append(".").append(sqlColumn.getColumnName()).append(" ");
            SQL().append(typedThis.LT()).append(typedThis.V(value));
        });
        typedThis.AND();
        return children;
    }

    @Override
    public Children LT(boolean condition, SqlFun<T, ?> column, Object value) {
        if (condition) {
            LT(column, value);
        }
        return children;
    }

    @Override
    public Children LE(SqlFun<T, ?> column, Object value) {
        typedThis.getFunFieldName(column, sqlColumn -> {
            SQL().append(sqlColumn.getTableName()).append(".").append(sqlColumn.getColumnName()).append(" ");
            SQL().append(typedThis.LE()).append(typedThis.V(value));
        });
        typedThis.AND();
        return children;
    }

    @Override
    public Children LE(boolean condition, SqlFun<T, ?> column, Object value) {
        if (condition) {
            LE(column, value);
        }
        return children;
    }

    @Override
    public String getSqlSegment() {
        String sqlSegment = super.getSqlSegment();
        return andTrim(sqlSegment);
    }

    @Override
    public String sql() {
        String sql = super.sql();
        return andTrim(sql);
    }

    private String andTrim(String sql) {
        //去掉结尾的 AND
        if (sql.endsWith("AND")) {
            sql = sql.substring(0, sql.length() - 3);
        }
        return sql;
    }
}
